package com.hsurosy.hsuchain.nft.user.domain.entity;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.github.houbb.sensitive.annotation.strategy.SensitiveStrategyPhone;
import com.hsurosy.hsuchain.nft.api.user.constant.UserRole;
import com.hsurosy.hsuchain.nft.api.user.constant.UserStateEnum;
import com.hsurosy.hsuchain.nft.datasource.domain.entity.BaseEntity;
import com.hsurosy.hsuchain.nft.user.infrastructure.mapper.AesEncryptTypeHandler;
import lombok.Data;

import java.util.Date;

/**
 * 用户实体类
 *
 * @Author Hsu琛君珩
 * @Date 2024-10-05 18:59
 * @Description
 * @Version: v1.0.0
 */
@Data
@TableName("users")
public class User extends BaseEntity {

    /**
     * 用户昵称
     */
    private String nickName;

    /**
     * 密码的 MD5 哈希值
     */
    private String passwordHash;

    /**
     * 用户状态
     */
    private UserStateEnum state;

    /**
     * 邀请码
     */
    private String inviteCode;

    /**
     * 邀请人用户ID
     */
    private String inviterId;

    /**
     * 手机号码，使用脱敏策略进行处理
     */
    @SensitiveStrategyPhone
    private String telephone;

    /**
     * 最后登录时间
     */
    private Date lastLoginTime;

    /**
     * 用户头像的URL
     */
    private String profilePhotoUrl;

    /**
     * 区块链地址
     */
    private String blockChainUrl;

    /**
     * 区块链平台
     */
    private String blockChainPlatform;

    /**
     * 是否通过实名认证
     */
    private Boolean certification;

    /**
     * 真实姓名，使用AES加密存储
     */
    @TableField(typeHandler = AesEncryptTypeHandler.class)
    private String realName;

    /**
     * 身份证号的加密哈希值
     */
    @TableField(typeHandler = AesEncryptTypeHandler.class)
    private String idCardNo;

    /**
     * 用户角色，表示用户是客户还是管理员
     */
    private UserRole userRole;

    /**
     * 注册新用户
     *
     * @param telephone 电话号码
     * @param nickName 昵称
     * @param password 密码
     * @param inviteCode 邀请码
     * @param inviterId 邀请人的用户ID
     * @return 当前用户实例
     */
    public User register(String telephone, String nickName, String password, String inviteCode, String inviterId) {
        this.setTelephone(telephone);
        this.setNickName(nickName);
        this.setPasswordHash(DigestUtil.md5Hex(password));
        this.setState(UserStateEnum.INIT);
        this.setUserRole(UserRole.CUSTOMER);
        this.setInviteCode(inviteCode);
        this.setInviterId(inviterId);
        return this;
    }

    /**
     * 注册管理员
     *
     * @param telephone 电话号码
     * @param nickName 昵称
     * @param password 密码
     * @return 当前用户实例
     */
    public User registerAdmin(String telephone, String nickName, String password) {
        this.setTelephone(telephone);
        this.setNickName(nickName);
        this.setPasswordHash(DigestUtil.md5Hex(password));
        this.setState(UserStateEnum.ACTIVE);
        this.setUserRole(UserRole.ADMIN);
        return this;
    }

    /**
     * 实名认证
     *
     * @param realName 真实姓名
     * @param idCard 身份证号
     * @return 当前用户实例
     */
    public User auth(String realName, String idCard) {
        this.setRealName(realName);
        this.setIdCardNo(idCard);
        this.setCertification(true);
        this.setState(UserStateEnum.AUTH);
        return this;
    }

    /**
     * 激活区块链账户
     *
     * @param blockChainUrl 区块链地址
     * @param blockChainPlatform 区块链平台
     * @return 当前用户实例
     */
    public User active(String blockChainUrl, String blockChainPlatform) {
        this.setBlockChainUrl(blockChainUrl);
        this.setBlockChainPlatform(blockChainPlatform);
        this.setState(UserStateEnum.ACTIVE);
        return this;
    }

    /**
     * 判断用户是否能够修改信息
     *
     * @return true 如果用户状态允许修改信息，false 否则
     */
    public boolean canModifyInfo() {
        return state == UserStateEnum.INIT || state == UserStateEnum.AUTH || state == UserStateEnum.ACTIVE;
    }
}
